-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
fix: resolve incorrect endpoints for database bulk actions (#1626) #1629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Update bulk action endpoints for database services: - Use `/api/trpc/redis.start` and `/api/trpc/redis.stop` for Redis - Use `/api/trpc/postgres.start` and `/api/trpc/postgres.stop` for PostgreSQL - Retain `/api/trpc/compose.start` and `/api/trpc/compose.stop` for Docker Compose services Tested with a project including Gitea, Redis, and PostgreSQL. Bulk start/stop operations now function correctly for all service types. Closes #1626
|
Hey @krokodaws please check this too https://github.com/krokodaws/dokploy/pull/1 I have refactored code to make it simpler. It's a staggered PR so needed to merge https://github.com/krokodaws/dokploy/pull/1 into #1629 |
| const handleBulkAction = async ( | ||
| action: "start" | "stop" | "move" | "delete", | ||
| extraParams: { targetProjectId?: string } = {}, | ||
| ) => { | ||
| let success = 0; | ||
| setIsBulkActionLoading(true); | ||
| for (const serviceId of selectedServices) { | ||
| try { | ||
| await composeActions.start.mutateAsync({ composeId: serviceId }); | ||
| success++; | ||
| } catch (_error) { | ||
| toast.error(`Error starting service ${serviceId}`); | ||
| } | ||
| } | ||
| if (success > 0) { | ||
| toast.success(`${success} services started successfully`); | ||
| refetch(); | ||
| } | ||
| setIsBulkActionLoading(false); | ||
| setSelectedServices([]); | ||
| setIsDropdownOpen(false); | ||
| }; | ||
|
|
||
| const handleBulkStop = async () => { | ||
| let success = 0; | ||
| setIsBulkActionLoading(true); | ||
| for (const serviceId of selectedServices) { | ||
| try { | ||
| await composeActions.stop.mutateAsync({ composeId: serviceId }); | ||
| success++; | ||
| } catch (_error) { | ||
| toast.error(`Error stopping service ${serviceId}`); | ||
| } | ||
| } | ||
| if (success > 0) { | ||
| toast.success(`${success} services stopped successfully`); | ||
| refetch(); | ||
| } | ||
| setSelectedServices([]); | ||
| setIsDropdownOpen(false); | ||
| setIsBulkActionLoading(false); | ||
| }; | ||
| const service = filteredServices.find((s) => s.id === serviceId); | ||
| if (!service) continue; | ||
|
|
||
| const handleBulkMove = async () => { | ||
| if (!selectedTargetProject) { | ||
| toast.error("Please select a target project"); | ||
| return; | ||
| } | ||
| const actions = | ||
| serviceActionsMap[service.type as keyof typeof serviceActionsMap]; | ||
| const mutation = actions?.[action]; | ||
|
|
||
| if (!mutation) continue; | ||
|
|
||
| let success = 0; | ||
| setIsBulkActionLoading(true); | ||
| for (const serviceId of selectedServices) { | ||
| try { | ||
| const service = filteredServices.find((s) => s.id === serviceId); | ||
| if (!service) continue; | ||
| const payload: Record<string, any> = { | ||
| [`${service.type}Id`]: serviceId, | ||
| }; | ||
|
|
||
| switch (service.type) { | ||
| case "application": | ||
| await applicationActions.move.mutateAsync({ | ||
| applicationId: serviceId, | ||
| targetProjectId: selectedTargetProject, | ||
| }); | ||
| break; | ||
| case "compose": | ||
| await composeActions.move.mutateAsync({ | ||
| composeId: serviceId, | ||
| targetProjectId: selectedTargetProject, | ||
| }); | ||
| break; | ||
| case "postgres": | ||
| await postgresActions.move.mutateAsync({ | ||
| postgresId: serviceId, | ||
| targetProjectId: selectedTargetProject, | ||
| }); | ||
| break; | ||
| case "mysql": | ||
| await mysqlActions.move.mutateAsync({ | ||
| mysqlId: serviceId, | ||
| targetProjectId: selectedTargetProject, | ||
| }); | ||
| break; | ||
| case "mariadb": | ||
| await mariadbActions.move.mutateAsync({ | ||
| mariadbId: serviceId, | ||
| targetProjectId: selectedTargetProject, | ||
| }); | ||
| break; | ||
| case "redis": | ||
| await redisActions.move.mutateAsync({ | ||
| redisId: serviceId, | ||
| targetProjectId: selectedTargetProject, | ||
| }); | ||
| break; | ||
| case "mongo": | ||
| await mongoActions.move.mutateAsync({ | ||
| mongoId: serviceId, | ||
| targetProjectId: selectedTargetProject, | ||
| }); | ||
| break; | ||
| if (action === "move" && extraParams.targetProjectId) { | ||
| payload.targetProjectId = extraParams.targetProjectId; | ||
| } | ||
| success++; | ||
| } catch (error) { | ||
| toast.error( | ||
| `Error moving service ${serviceId}: ${error instanceof Error ? error.message : "Unknown error"}`, | ||
| ); | ||
| } | ||
| } | ||
| if (success > 0) { | ||
| toast.success(`${success} services moved successfully`); | ||
| refetch(); | ||
| } | ||
| setSelectedServices([]); | ||
| setIsDropdownOpen(false); | ||
| setIsMoveDialogOpen(false); | ||
| setIsBulkActionLoading(false); | ||
| }; | ||
|
|
||
| const handleBulkDelete = async () => { | ||
| let success = 0; | ||
| setIsBulkActionLoading(true); | ||
| for (const serviceId of selectedServices) { | ||
| try { | ||
| const service = filteredServices.find((s) => s.id === serviceId); | ||
| if (!service) continue; | ||
|
|
||
| switch (service.type) { | ||
| case "application": | ||
| await applicationActions.delete.mutateAsync({ | ||
| applicationId: serviceId, | ||
| }); | ||
| break; | ||
| case "compose": | ||
| await composeActions.delete.mutateAsync({ | ||
| composeId: serviceId, | ||
| deleteVolumes: false, | ||
| }); | ||
| break; | ||
| case "postgres": | ||
| await postgresActions.delete.mutateAsync({ | ||
| postgresId: serviceId, | ||
| }); | ||
| break; | ||
| case "mysql": | ||
| await mysqlActions.delete.mutateAsync({ | ||
| mysqlId: serviceId, | ||
| }); | ||
| break; | ||
| case "mariadb": | ||
| await mariadbActions.delete.mutateAsync({ | ||
| mariadbId: serviceId, | ||
| }); | ||
| break; | ||
| case "redis": | ||
| await redisActions.delete.mutateAsync({ | ||
| redisId: serviceId, | ||
| }); | ||
| break; | ||
| case "mongo": | ||
| await mongoActions.delete.mutateAsync({ | ||
| mongoId: serviceId, | ||
| }); | ||
| break; | ||
| if (action === "delete" && service.type === "compose") { | ||
| payload.deleteVolumes = false; | ||
| } | ||
|
|
||
| await mutation.mutateAsync(payload); | ||
| success++; | ||
| } catch (error) { | ||
| toast.error( | ||
| `Error deleting service ${serviceId}: ${error instanceof Error ? error.message : "Unknown error"}`, | ||
| ); | ||
| toast.error(`Error during ${action} of service ${serviceId}`); | ||
| } | ||
| } | ||
|
|
||
| if (success > 0) { | ||
| toast.success(`${success} services deleted successfully`); | ||
| toast.success(`${success} services ${action}ed successfully`); | ||
| refetch(); | ||
| } | ||
| setIsBulkActionLoading(false); | ||
| setSelectedServices([]); | ||
| setIsDropdownOpen(false); | ||
| setIsBulkActionLoading(false); | ||
| if (action === "move") setIsMoveDialogOpen(false); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather have the way we had it, I feel it's easier to add and modify, than a method that is somewhat complex
Could you simply add the missing mutations to each object in the service?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I've returned all the changes to their original form.
b38da16 to
eff2657
Compare
Update bulk action endpoints for database services:
/api/trpc/redis.startand/api/trpc/redis.stopfor Redis/api/trpc/postgres.startand/api/trpc/postgres.stopfor PostgreSQL/api/trpc/compose.startand/api/trpc/compose.stopfor Docker Compose servicesTested with a project including Gitea, Redis, and PostgreSQL. Bulk start/stop operations now function correctly for all service types.
Closes #1626